#include "ActionOpt.h"


CActionOpt::CActionOpt()
{
}

CActionOpt::~CActionOpt()
{
}

bool CActionOpt::Exists(const String &path)
{
	return SPIFFS.exists(path);
}

bool CActionOpt::ReadHeader(const String &path, AeActHeader_t &header)
{
	bool error = false;

	File file;
	do {
		if (!Exists(path)) {
			error = true;
			break;
		}
		file = SPIFFS.open(path, FILE_READ);
		if (!file) {
			error = true;
			break;
		}
		if (file.size() < sizeof(AeActHeader_t)) {
			error = true;
			break;
		}
		uint32_t dataSize = file.size() - sizeof(AeActHeader_t);
		if (0 != (dataSize % sizeof(AeActPose_t))) {
			error = true;
			break;
		}
		uint32_t seqCnt = dataSize / sizeof(AeActPose_t);
		size_t readed = file.readBytes((char *)&header, sizeof(AeActHeader_t));
		if (readed != sizeof(AeActHeader_t)) {
			error = true;
			break;
		}
		if (seqCnt != header.seqCnt) {
			error = true;
			break;
		}
	} while(false);
	if (file) {
		file.close();
	}

	return (!error);
}

bool CActionOpt::ReadPose(const String &path, uint32_t seq, AeActPose_t &pose)
{
	bool error = false;

	File file;
	do {
		if (!Exists(path)) {
			error = true;
			break;
		}
		file = SPIFFS.open(path, FILE_READ);
		if (!file) {
			error = true;
			break;
		}
		uint32_t offset = sizeof(AeActHeader_t) + seq * sizeof(AeActPose_t);
		if (file.size() < offset + sizeof(AeActPose_t)) {
			error = true;
			break;
		}
		if (!file.seek(offset, SeekSet)) {
			error = true;
			break;
		}
		size_t readed = file.readBytes((char *)&pose, sizeof(AeActPose_t));
		if (readed != sizeof(AeActPose_t)) {
			error = true;
			break;
		}
		if (seq != pose.seq) {
			error = true;
			break;
		}
	} while(false);
	if (file) {
		file.close();
	}

	return (!error);
}

bool CActionOpt::WriteHeader(const String &path, const AeActHeader_t &header)
{
	bool error = false;

	File file;
	do {
		file = SPIFFS.open(path, FILE_WRITE);
		if (!file) {
			error = true;
			break;
		}
		if (sizeof(AeActHeader_t) != file.write((uint8_t *)&header, sizeof(AeActHeader_t))) {
			error = true;
			break;
		}
	} while(false);
	if (file) {
		file.close();
	}

	if (error) {
		SPIFFS.remove(path);
	}

	return (!error);
}

bool CActionOpt::WritePose(const String &path, uint32_t seq, const AeActPose_t &pose)
{
	bool error = false;

	File file;
	do {
		if (!Exists(path)) {
			error = true;
			break;
		}
		file = SPIFFS.open(path, FILE_APPEND);
		if (!file) {
			error = true;
			break;
		}
		uint32_t offset = sizeof(AeActHeader_t) + seq * sizeof(AeActPose_t);
		if (file.size() < offset) {
			error = true;
			break;
		}
		if (!file.seek(offset, SeekSet)) {
			error = true;
			break;
		}
		if (sizeof(AeActPose_t) != file.write((uint8_t *)&pose, sizeof(AeActPose_t))) {
			error = true;
			break;
		}
	} while(false);
	if (file) {
		file.close();
	}

	if (error) {
		SPIFFS.remove(path);
	}

	return (!error);
}

bool CActionOpt::UpdateHeader(const String &path, const AeActHeader_t &header)
{
	bool error = false;

	File file;
	do {
		if (!Exists(path)) {
			error = true;
			break;
		}
		file = SPIFFS.open(path, "r+");
		if (!file) {
			error = true;
			break;
		}
		if (!file.seek(0, SeekSet)) {
			error = true;
			break;
		}
		if (sizeof(AeActHeader_t) != file.write((uint8_t *)&header, sizeof(AeActHeader_t))) {
			error = true;
			break;
		}
	} while(false);
	if (file) {
		file.close();
	}

	if (error) {
		SPIFFS.remove(path);
	}

	return (!error);
}

